
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "tim.h"
#include "APP_Loop.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "ds1302.h"
#include "stm32f0xx_usart.h"
#include "IR_Control.h"
#include "HLW8110.h"
#include "ds18b20.h"
#include "Flash_ops.h"
#include "parameter.h"
#include "Lora.h"

/* USER CODE END Includes */

union str_CurrentTime str_DevCurrentTime;

unsigned char uc_EventFlag = 0;
unsigned char uc_autoModeFlag = 1;
unsigned char uc_RelayStatus = 0; //继电器状态
int i;
short temperature;
unsigned char uc_RemoteOpenFlag = 0; // 1:开：2关
unsigned int ui_RemoteAdjustIRCode = 0;

unsigned char TimeCtrlCount;
//目前Lora接收支持 10节课时控参数
union uTimeCtrlPara str_TimeCtrl_Param;
union uDevicePara str_Device_Param;


//接收到路由器上报心跳事件通知，全部等待逐个轮询上报心跳。
unsigned char uc_ReportHeartEventFlag = 0;
unsigned char uc_SetParaStatus = 1;
unsigned char uc_RestoreDefaultSet = 0;

void TempControlProcess(void);
void TimeControlProcess(void);
void OpenAirConditoner(void);
void CloseAirConditoner(void);
void Relay_GPIO_Init(void);
void Key_GPIO_Init(void);
void SystemRestart(void);
void DevDefaultPara(void);
unsigned char IsDuringClassTime(void);

void main_Loop(void)
{
  int i=0;
	
	Key_GPIO_Init();
	Relay_GPIO_Init();
	Lora_GPIO_Init();
	Init_HLW8110();
	InitClock();

	DS18B20_Init();

	 while(DS18B20_Init())
	 {
		i++;
		 if(i > 100)
					break;
		printf("DS18B20 Error\r\n");
		HAL_Delay(5);
	 }

	str_Lora_RecvDeal.UartRxDeal_Flag = 1;
	str_LocalIR_Para.GetAirParaCount = 0;

	//test start
	 
//	 while(1)
//	{
//		str_LocalIR_Para.GetAirParaCount = 0;
//		Get_Air_ConditonData();
//		printf("fromat:%d\r\n",str_LocalIR_Para.fromat);
//		printf("AirState:%d\r\n",str_LocalIR_Para.AirState);
//		printf("AirTemp:%d\r\n",str_LocalIR_Para.AirTemp);
//		printf("AirModel:%d\r\n",str_LocalIR_Para.AirModel);
//		HAL_Delay(5000);
//	}
	
//	while(1)
//	{
//		unsigned char uc_buf[8];
//		uc_buf[0] = 0xAA;
//		uc_buf[1] = 0x55;
//		uc_buf[2] = 0xCC;
//		uc_buf[3] = 0x33;
////			HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_6);
////			HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);
////		printf("fromat:%d\r\n",str_LocalIR_Para.fromat);
//		HAL_Delay(500);
//		HAL_UART_Transmit(&huart3, uc_buf, 4,0xFFFF);
//		while(HAL_UART_GetState(&huart3) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
//				 
//	}
	
//	while(1)
//	{
//
//		TimeCtrlCount = 3;
//		str_TimeCtrl_Param.uc_DevTimeParm[0][0] = 8;
//		str_TimeCtrl_Param.uc_DevTimeParm[1][0] = 30;
//		str_TimeCtrl_Param.uc_DevTimeParm[2][0] = 12;
//		str_TimeCtrl_Param.uc_DevTimeParm[3][0] = 0;
//
//		str_TimeCtrl_Param.uc_DevTimeParm[0][1] = 13;
//		str_TimeCtrl_Param.uc_DevTimeParm[1][1] = 30;
//		str_TimeCtrl_Param.uc_DevTimeParm[2][1] = 18;
//		str_TimeCtrl_Param.uc_DevTimeParm[3][1] = 0;
//
//		str_TimeCtrl_Param.uc_DevTimeParm[0][2] = 19;
//		str_TimeCtrl_Param.uc_DevTimeParm[1][2] = 0;
//		str_TimeCtrl_Param.uc_DevTimeParm[2][2] = 22;
//		str_TimeCtrl_Param.uc_DevTimeParm[3][2] = 0;
//
//		writeFlash();
//
//		ReadDevPara();//read flash
//
//		printf("TimeCtrlCount:%d\r\n",TimeCtrlCount);
//
//		for(i=0;i<6;i++)
//		{
//			printf("StartTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i]);
//			printf("StartTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[i]);
//
//			printf("EndTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i]);
//			printf("EndTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[i]);
//		}
//
//
//		HAL_Delay(1000);
//	}
	//test end

	ReadDevPara();//read flash
	DevDefaultPara();
	
	#ifndef RS485_EN
	ReadLoraPara();
 
	SET_M0_L;
	SET_M1_L;
	HAL_Delay(30);
	str_Device_Param.str_DeviceParam.Channel = 0x19;
	#endif

	Get_Air_ConditonData();
//	printf("Format:%d\r\n",str_LocalIR_Para.fromat);
//	printf("state:%d\r\n",str_LocalIR_Para.AirState);
//	printf("temp:%d\r\n",str_LocalIR_Para.AirTemp);
//	printf("mode:%d\r\n",str_LocalIR_Para.AirModel);

//	str_DevCurrentTime.str_CurrentTime.Year = 24;
//	str_DevCurrentTime.str_CurrentTime.Month = 8;
//	str_DevCurrentTime.str_CurrentTime.Day = 18;
//
//	str_DevCurrentTime.str_CurrentTime.Hour = 9;
//	str_DevCurrentTime.str_CurrentTime.Min = 50;
//	str_DevCurrentTime.str_CurrentTime.Sec = 0;
//	str_DevCurrentTime.str_CurrentTime.Week = 7;
//
//	DecToHex(str_DevCurrentTime.tt);
//	SyncDS1302Time(str_DevCurrentTime.tt);
//	SetAirTemperature(0x18);

//	str_Device_Param.str_DeviceParam.IRUseDefCodeFlag = 1;
//	HAL_Delay(20);
//	uc_RemoteOpenFlag = 1;//test open air
//	SetAirTemperatureUp(); //test air temp
	//OpenRelay;
	
	uc_EventFlag = 1;//设备开机/重启上报一次设备状态。
	while(1)
	{
		#ifndef RS485_EN
	  if(uc_SetLoraNumFlag)
		{
			uc_SetLoraNumFlag = 0;
			SetLoraNodeNum();
		}
		#endif
		if(uc_RestoreDefaultSet)
		{
			uc_RestoreDefaultSet=0;
			EraseDataFromFlash();
			HAL_Delay(10);
			ReadDevPara();//read flash
			#ifndef RS485_EN
			Lora_InitPara();
			SET_M0_L;
			SET_M1_L;
			HAL_Delay(30);
			#endif
			
			DevDefaultPara();
		}
		
	if(uc_IRLearnFlag)
	{
		HAL_Delay(20);
		uc_SetParaStatus = ReadIRLearnStatus();
		uc_EventFlag = 6;
		uc_IRLearnFlag++;
		if(uc_IRLearnFlag > 5)
			uc_IRLearnFlag = 0;
	}
		if((str_DevCurrentTime.str_CurrentTime.Min == 30)&&
		(str_DevCurrentTime.str_CurrentTime.Sec == 00))
							Get_Air_ConditonData();
	HAL_Delay(20);
	Read_HLW8110_Data();

//	printf("DevVoltage:%d\r\n",str_DevPowerData.DevVoltage);
//	printf("DevCurrentFlow:%d\r\n",str_DevPowerData.DevCurrentFlow);
//	printf("DevCurrentPower:%d\r\n",str_DevPowerData.DevCurrentPower);
//	printf("DevQuantityElect:%d\r\n",str_DevPowerData.DevQuantityElect);

//	ReadDS1302Clock(str_DevCurrentTime.tt);
	ReadDS1302ClockConvertDec(str_DevCurrentTime.tt);

	printf("1302:%d-%d-%d %d:%d:%d -- %d\r\n",str_DevCurrentTime.str_CurrentTime.Year,
			str_DevCurrentTime.str_CurrentTime.Month,
			str_DevCurrentTime.str_CurrentTime.Day,
			str_DevCurrentTime.str_CurrentTime.Hour,
			str_DevCurrentTime.str_CurrentTime.Min,
			str_DevCurrentTime.str_CurrentTime.Sec,
			str_DevCurrentTime.str_CurrentTime.Week);

	//凌晨1:30 重启设备
	if((str_DevCurrentTime.str_CurrentTime.Hour == 01) && 
		(str_DevCurrentTime.str_CurrentTime.Min == 30)&&
		(str_DevCurrentTime.str_CurrentTime.Sec == 00))
			if(GetRelayStatus == CLOSE)
										SystemRestart();
	
	temperature=DS18B20_Get_Temp();

	if(temperature<0)
	  {
		temperature=-temperature;	//转为正数
	  }

//	printf("temperature:%d\r\n",temperature);
	printf("temperature=%d.%d\r\n",temperature/10,temperature%10);

	if(uc_autoModeFlag)
	{
		switch(str_Device_Param.str_DeviceParam.WorkMode)
			{
				case 0:
					//空闲模式
					HAL_Delay(1);
				break;
				case 1:
				//温控模式
					TempControlProcess();
				break;
				case 2:
				//时控模式
					TimeControlProcess();
				break;
			}
	}

	RecvLoraData();//优先Report remote info
//	HAL_UART_MspDeInit(&huart2);
//	HAL_Delay(100);
//	HAL_UART_MspInit(&huart2);
//	HAL_Delay(100);
	
//	if(uc_EventFlag)
//		__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
	
	if(uc_RemoteOpenFlag == 1)
	{
		ReprotAdjustEvent(uc_EventFlag);
		OpenAirConditoner();
		uc_RemoteOpenFlag = 0;
		uc_autoModeFlag = 0;
		ui_LocalIdleWorkMin = 0;
	}
	else if(uc_RemoteOpenFlag == 2)
	{
		ReprotAdjustEvent(uc_EventFlag);
		CloseAirConditoner();
		uc_RemoteOpenFlag = 0;
		uc_autoModeFlag = 0;
		ui_LocalIdleWorkMin = 0;
	}

	if(ui_RemoteAdjustIRCode)
	{
		int i;
		for(i=0;i<3;i++)
		{
			SetAirFormat(ui_RemoteAdjustIRCode);
			HAL_Delay(30);
			GetCurrentAirCode();
			if(str_LocalIR_Para.fromat == ui_RemoteAdjustIRCode)
				break;
		}
		ui_RemoteAdjustIRCode = 0;
	}

	if(uc_ReportHeartEventFlag == 0)
	{
		int i;
		//重发机制：3次 等待路由器 ACK
		for(i=0;i<3;i++)
		{
			if(uc_EventFlag > 4)
			{
				//ACK
				ReprotAdjustEvent(uc_EventFlag);
			}
			else if(uc_EventFlag)
			{
				//上报本地事件
				str_LocalIR_Para.GetAirParaCount = 0;
				Get_Air_ConditonData();
				Read_HLW8110_Data();
				ReprotEvent(uc_EventFlag);
			}
			else
				break;

			RecvLoraData();
			HAL_Delay(1000);
		}

		uc_EventFlag = 0;
	}

		//test
		HAL_Delay(500);
//		HeartReport();
	}

}

void DevDefaultPara(void)
{
int i;
	if(str_Device_Param.str_DeviceParam.WorkMode == 0xff)
			str_Device_Param.str_DeviceParam.WorkMode = 0;
	//	if(str_Device_Param.str_DeviceParam.DevNum == 0xff)

		if(str_Device_Param.str_DeviceParam.Channel == 0xff)
			str_Device_Param.str_DeviceParam.Channel = 0x19;
		if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag == 0xff)
			str_Device_Param.str_DeviceParam.IRUseDefCodeFlag = 0;
		if(str_Device_Param.str_DeviceParam.LocalManualWorkTime == 0xff)
			str_Device_Param.str_DeviceParam.LocalManualWorkTime = 720;//12H
		if(str_Device_Param.str_DeviceParam.Temperature_H == 0xff)
			str_Device_Param.str_DeviceParam.Temperature_H = 30;
		if(str_Device_Param.str_DeviceParam.Temperature_L == 0xff)
			str_Device_Param.str_DeviceParam.Temperature_L = 21;


		if(TimeCtrlCount == 0xff)
		{
			TimeCtrlCount = 2;
			str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[0] = 8;
			str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[0] = 30;
			str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[1] = 13;
			str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[1] = 30;

			str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[0] = 12;
			str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[0] = 0;
			str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[1] = 22;
			str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[1] = 0;
		}

		printf("DevNum:%x\r\n",str_Device_Param.str_DeviceParam.DevNum);
		printf("Channel:%x\r\n",str_Device_Param.str_DeviceParam.Channel);
		printf("AirContronlMode:%x\r\n",str_Device_Param.str_DeviceParam.AirContronlMode);
		printf("WorkMode:%x\r\n",str_Device_Param.str_DeviceParam.WorkMode);
		printf("Temperature_L:%d\r\n",str_Device_Param.str_DeviceParam.Temperature_L);
		printf("Temperature_H:%d\r\n",str_Device_Param.str_DeviceParam.Temperature_H);
		printf("IRUseDefCodeFlag:%x\r\n",str_Device_Param.str_DeviceParam.IRUseDefCodeFlag);

		//debug
		for(i=0;i<5;i++)
		{
			printf("StartTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i]);
			printf("StartTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[i]);

			printf("EndTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i]);
			printf("EndTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[i]);
		}
		//debug
}

void TempControlProcess(void)
{
	if(str_DevCurrentTime.str_CurrentTime.Week < 6) //排除周末
	{
	  if(((str_DevCurrentTime.str_CurrentTime.Hour > (str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[0] - 1)) &&
		(str_DevCurrentTime.str_CurrentTime.Min > str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[0]))&&
		((str_DevCurrentTime.str_CurrentTime.Hour < (str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[TimeCtrlCount] + 1))&&
		 (str_DevCurrentTime.str_CurrentTime.Min < str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[TimeCtrlCount])))
		{

			if(temperature > (str_Device_Param.str_DeviceParam.Temperature_H*10))
			{
				
				if(GetRelayStatus == CLOSE)
							uc_EventFlag = 2;
				//open
				OpenAirConditoner();
				
			}else if(temperature < (str_Device_Param.str_DeviceParam.Temperature_L * 10))
			{
				if(GetRelayStatus == OPEN)
							uc_EventFlag = 2;
				
				//close
				CloseAirConditoner();
			}

		}
	}

}

void OpenAirConditoner(void)
{
	static unsigned char IR_openAirCount = 0;
	if(GetRelayStatus == CLOSE)
	{
		IR_openAirCount = 0;
		OpenRelay;
		HAL_Delay(2000);
		//红外开空调
	}
	
	if((str_DevPowerData.DevCurrentFlow < 500)&&(IR_openAirCount < 5))
	{
		IR_openAirCount++;
		HAL_Delay(2000);
		if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag)
			ContrlUseLearnChannel(1);
		else
			openAirCondit();
	}
	
}
void CloseAirConditoner(void)
{
	if(GetRelayStatus == OPEN)
	{
		//红外关空调
		if(str_Device_Param.str_DeviceParam.IRUseDefCodeFlag)
			ContrlUseLearnChannel(2);
		else
			CloseAirCondit();
		//1S 后 最后5S以上断电
		HAL_Delay(8000);
		//小于25W断电
		if(str_DevPowerData.DevCurrentFlow < 12)
				CloseRelay;
	}
}

void TimeControlProcess(void)
{
	
	if(str_DevCurrentTime.str_CurrentTime.Week < 6) //排除周末
	{
		if(IsDuringClassTime())
		{
			printf("Is ClassTime\r\n");
			
				if(GetRelayStatus == CLOSE)
						uc_EventFlag = 3;
				
				OpenAirConditoner();
		}
		else
		{
			if(GetRelayStatus == OPEN)
								uc_EventFlag = 3;
				
					CloseAirConditoner();
		}
	}
}

/*
*@ret:1 课中时间，0：课间时间
*/
unsigned char IsDuringClassTime(void)
{
	int i;
	//Debug
//	printf("TimeCtrlCount:%d\r\n",TimeCtrlCount);
//	for(i=0;i<TimeCtrlCount;i++)
//	{
//		printf("StartTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i]);
//		printf("StartTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[i]);

//		printf("EndTime_H[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i]);
//		printf("EndTime_M[%d]:%d\r\n",i,str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[i]);
//	}
	//Debug
	for(i=0;i<TimeCtrlCount;i++)
	{
		if((str_DevCurrentTime.str_CurrentTime.Hour == str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i]) && 
			(str_DevCurrentTime.str_CurrentTime.Min > str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_M[i]))
		{
			if(str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i] == str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i])
			{
				if(str_DevCurrentTime.str_CurrentTime.Min < str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[i])
						return 1;
					
			}
			else
			{
				if(str_DevCurrentTime.str_CurrentTime.Hour < str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i])
					return 1;
			}
			
		}
		else if((str_DevCurrentTime.str_CurrentTime.Hour > str_TimeCtrl_Param.str_TimeCtrlParam.StartTime_H[i]) &&
			(str_DevCurrentTime.str_CurrentTime.Hour < str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i]))
		{
					return 1;
		}
		else if((str_DevCurrentTime.str_CurrentTime.Hour == str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_H[i]) && 
			(str_DevCurrentTime.str_CurrentTime.Min < str_TimeCtrl_Param.str_TimeCtrlParam.EndTime_M[i]))
						return 1;
	}
	
	return 0;
}

void Key_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOC_CLK_ENABLE();
	GPIO_InitStruct.Pin = GPIO_PIN_13;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

void Relay_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	GPIO_InitStruct.Pin = GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	CloseRelay;
}


void SystemRestart(void)
{
//	__set_FAULTMASK(1);//关闭总中断
//	__disable_fault_irq();
//	NVIC_DisableIRQ;
	__ASM volatile ("cpsid i");
	HAL_NVIC_SystemReset();
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	
	printf("HAL_UART_ErrorCallback\r\n");
	
//	if(HAL_UART_GetError(&huart2) & HAL_UART_ERROR_ORE)
//   {
//        __HAL_UART_FLUSH_DRREGISTER(&huart2);  //读DR寄存器，就可以清除ORE错误标志位
//   }
//	if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_ORE))
//	{
//		__HAL_UART_CLEAR_OREFLAG(&huart2);
//		__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
//	}
	
	if(HAL_UART_GetError(huart) & HAL_UART_ERROR_ORE)
   {
        __HAL_UART_FLUSH_DRREGISTER(huart);  //读DR寄存器，就可以清除ORE错误标志位
   }
	if(__HAL_UART_GET_FLAG(huart,UART_FLAG_ORE))
	{
		__HAL_UART_CLEAR_OREFLAG(huart);
		__HAL_UART_ENABLE_IT(huart,UART_IT_RXNE);
	}
	if(huart->ErrorCode & HAL_UART_ERROR_ORE)
	{
		uint32_t tmp = huart->Instance->ISR;
		tmp = huart->Instance->RDR;
		huart->Instance->CR1 |= UART_IT_RXNE;
	}
}
